/*
 * Copyright (C) 2011-2012 Andrew Wells
 *
 * Licensed under the GNU License, Version 3
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.gnu.org/copyleft/gpl.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * Dungeons & Dragons Copyright (C) Wizards of the Coast. I do not claim
 * the right to any information used from their books or resources.
 */

package com.trace.wells.charactertracker;

import java.io.Serializable;

public class Info implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private boolean prepareSpellsIsChecked;

	//Money of the character
	private int PP, GP, SP, EP, CP;

	//The level the character is at an their expierience points
	private int experience;

	//Total and current health of the character
	private int totalHP, currentHP;

	//Whether the character is concious or not
	private boolean concious;

	//The character's current armor class.
	private int armorClass;

	//The initiative modifier (Determines if they are better at initiating a fight)
	private int initiativeMod;

	//DOTO: Remove the info.Weapon????
	//The current weapon drawn of the character (Not us
	private Weapon currentWeapon;

	//An array remembering which groups are expanded in the 
	private int[] groupIsExpanded;

	//The name, race, class, and allignment of the character
	private String name, race, alignment;

	//The age, height, and weight of the character
	private int age, height, weight;

	//Eye and hair color
	private String eyes, hair;

	//The size bonus received based on what race the character is
	private int bonusSize;

	//Initializes all the values of the character's info class.
	Info() {
		initializeExperience();
		initializeMoney();
		initializeStatus();
		initializeTraits();
	}

	//Sets all money to 0
	public void initializeMoney() {
		this.PP = 0;
		this.GP = 0;
		this.SP = 0;
		this.EP = 0;
		this.CP = 0;
	}

	// Sets all the attributes at once.
	public void setMoney(int PP, int GP, int SP, int EP, int CP) {
		this.PP = PP;
		this.GP = GP;
		this.SP = SP;
		this.EP = EP;
		this.CP = CP;
	}

	//Adjusts the money value based on what value you pass it.
	public void alterMoney(int PP, int GP, int SP, int EP, int CP) {
		this.PP += PP;
		this.GP += GP;
		this.SP += SP;
		this.EP += EP;
		this.CP += CP;
	}

	public void initializeExperience() {
		experience = -99;
	}

	public void alterExperience(int experience) {
		this.experience += experience;
	}

	//Gets the experience required for the next level
	public int getExpToNextLevel(int level) {
		int nextLevel = level + 1;
		int retVal = nextLevel * (nextLevel - 1) * 500;
		return retVal;
	}

	public void addToExperiencePoints(int num) {
		this.experience += num;
	}

	public void subtractFromExperiencePoints(int num) {
		this.experience -= num;
	}

	/**
	 * Alters Armor Class of the player by the amount it is passed
	 * 
	 * @param num
	 */
	public void alterArmorClass(int num) {
		this.armorClass += num;
	}

	public void initializeStatus() {
		initializeHealth();
		concious = true;
		armorClass = -99;
		initiativeMod = -99;
		currentWeapon = null;
		prepareSpellsIsChecked = true;
	}

	//Sets health to 0
	public void initializeHealth() {
		this.totalHP = 0;
		this.currentHP = 0;
	}

	// Default Constructor
	public void initializeTraits() {
		name = "";
		race = "";
		alignment = "";
		age = 0;
		height = 0;
		weight = 0;
		eyes = "";
		hair = "";
	}

	/**
	 * Applies size modifier to needed character information
	 * 
	 * @param race
	 * @return
	 */
	public void applySizeBonus(String race) {
		if (race == ConstantHelper.RACE_GNOME || race == ConstantHelper.RACE_HALFLING) {
			bonusSize = 1;
		} else
			bonusSize = 0;
	}

	public void increaseHealth(int additionalHealth, int conMod) {
		this.totalHP += additionalHealth + conMod;
		this.currentHP += additionalHealth + conMod;
	}

	public int[] getNumberOfSpellLevels(int level, String charClass) {
		int[] spellsPerDay = { 0 };
		if (charClass.equals(ConstantHelper.CLASS_BARD)) {
			spellsPerDay = ConstantHelper.SPELL_DAY_BARD[level];
		} else if (charClass.equals(ConstantHelper.CLASS_CLERIC)) {
			spellsPerDay = ConstantHelper.SPELL_DAY_CLERIC_DOMAIN[level];
		} else if (charClass.equals(ConstantHelper.CLASS_DRUID)) {
			spellsPerDay = ConstantHelper.SPELL_DAY_DRUID[level];
		} else if (charClass.equals(ConstantHelper.CLASS_PALADIN)) {
			spellsPerDay = ConstantHelper.SPELL_DAY_PALADIN[level];
		} else if (charClass.equals(ConstantHelper.CLASS_RANGER)) {
			spellsPerDay = ConstantHelper.SPELL_DAY_RANGER[level];
		} else if (charClass.equals(ConstantHelper.CLASS_SORCERER)) {
			spellsPerDay = ConstantHelper.SPELL_DAY_SORCERER[level];
		} else if (charClass.equals(ConstantHelper.CLASS_WIZARD)) {
			spellsPerDay = ConstantHelper.SPELL_DAY_WIZARD[level];
		} else
			spellsPerDay = new int[0];

		int[] binArray = new int[10];
		for (int i = 0; i < spellsPerDay.length; i++) {
			if (spellsPerDay[i] > 0)
				binArray[i] = 1;
			else
				binArray[i] = 0;
		}
		return binArray;
	}

	/**
	 * @return the bonusSize
	 */
	public int getBonusSize() {
		return bonusSize;
	}

	/**
	 * @param bonusSize
	 *            the bonusSize to set
	 */
	public void setBonusSize(int bonusSize) {
		this.bonusSize = bonusSize;
	}

	/**
	 * @return the pP
	 */
	public int getPP() {
		return PP;
	}

	/**
	 * @param pP
	 *            the pP to set
	 */
	public void setPP(int pP) {
		PP = pP;
	}

	/**
	 * @return the gP
	 */
	public int getGP() {
		return GP;
	}

	/**
	 * @param gP
	 *            the gP to set
	 */
	public void setGP(int gP) {
		GP = gP;
	}

	/**
	 * @return the sP
	 */
	public int getSP() {
		return SP;
	}

	/**
	 * @param sP
	 *            the sP to set
	 */
	public void setSP(int sP) {
		SP = sP;
	}

	/**
	 * @return the eP
	 */
	public int getEP() {
		return EP;
	}

	/**
	 * @param eP
	 *            the eP to set
	 */
	public void setEP(int eP) {
		EP = eP;
	}

	/**
	 * @return the cP
	 */
	public int getCP() {
		return CP;
	}

	/**
	 * @param cP
	 *            the cP to set
	 */
	public void setCP(int cP) {
		CP = cP;
	}

	/**
	 * @return the experience
	 */
	public int getExperience() {
		return experience;
	}

	/**
	 * @param experience
	 *            the experience to set
	 */
	public void setExperience(int experience) {
		this.experience = experience;
	}

	/**
	 * @return the totalHP
	 */
	public int getTotalHP() {
		return totalHP;
	}

	/**
	 * @param totalHP
	 *            the totalHP to set
	 */
	public void setTotalHP(int totalHP) {
		this.totalHP = totalHP;
	}

	/**
	 * @return the currentHP
	 */
	public int getCurrentHP() {
		return currentHP;
	}

	/**
	 * @param currentHP
	 *            the currentHP to set
	 */
	public void setCurrentHP(int currentHP) {
		this.currentHP = currentHP;
	}

	/**
	 * Asjusts the player's health by amt
	 */
	public void adjustHealth(int amt) {
		this.currentHP += amt;
	}

	/**
	 * @return the concious
	 */
	public boolean isConcious() {
		return concious;
	}

	/**
	 * Returns 1 if between 0 and -9
	 * 
	 * Returns 0 of at -10
	 * 
	 * Returns 2 of at 1 to maxHealth
	 * 
	 * @return
	 */
	public int getConciousState() {
		if (this.currentHP <= 0 && this.currentHP >= -9) {
			this.concious = false;
			return 1;
		} else if (this.currentHP == -10) {
			this.concious = false;
			return 0;
		} else {
			concious = true;
			return 2;
		}
	}

	/**
	 * @param concious
	 *            the concious to set
	 */
	public void setConcious(boolean concious) {
		this.concious = concious;
	}

	/**
	 * @return the armorClass
	 */
	public int getArmorClass() {
		return armorClass;
	}

	/**
	 * @param armorClass
	 *            the armorClass to set
	 */
	public void setArmorClass(int armorClass) {
		this.armorClass = armorClass;
	}

	/**
	 * @return the initiativeMod
	 */
	public int getInitiativeMod() {
		return initiativeMod;
	}

	/**
	 * @param initiativeMod
	 *            the initiativeMod to set
	 */
	public void setInitiativeMod(int initiativeMod) {
		this.initiativeMod = initiativeMod;
	}

	/**
	 * @return the currentWeapon
	 */
	public Weapon getCurrentWeapon() {
		return currentWeapon;
	}

	/**
	 * @param currentWeapon
	 *            the currentWeapon to set
	 */
	public void setCurrentWeapon(Weapon currentWeapon) {
		this.currentWeapon = currentWeapon;
	}

	public void setGroupIsExpanded(int[] groupIsExpanded) {
		this.groupIsExpanded = groupIsExpanded;
	}

	public int[] getGroupIsExpanded() {
		return groupIsExpanded;
	}

	public void setGroupIsExpandedElement(int pos, int val) {
		this.groupIsExpanded[pos] = val;
	}

	public void initializeGroupExpandedElement() {
		this.groupIsExpanded = new int[10];
		for (int i = 0; i < 10; i++) {
			this.groupIsExpanded[i] = 1;
		}
	}

	public int getGroupIsExpandedElement(int pos) {
		return this.groupIsExpanded[pos];
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the race
	 */
	public String getRace() {
		return race;
	}

	/**
	 * @param race
	 *            the race to set
	 */
	public void setRace(String race) {
		this.race = race;
	}

	/**
	 * @return the alignment
	 */
	public String getAlignment() {
		return alignment;
	}

	/**
	 * @param alignment
	 *            the alignment to set
	 */
	public void setAlignment(String alignment) {
		this.alignment = alignment;
	}

	/**
	 * @return the age
	 */
	public int getAge() {
		return age;
	}

	/**
	 * @param age
	 *            the age to set
	 */
	public void setAge(int age) {
		this.age = age;
	}

	/**
	 * @return the height
	 */
	public int getHeight() {
		return height;
	}

	/**
	 * @param height
	 *            the height to set
	 */
	public void setHeight(int height) {
		this.height = height;
	}

	/**
	 * @return the weight
	 */
	public double getWeight() {
		return weight;
	}

	/**
	 * @param weight
	 *            the weight to set
	 */
	public void setWeight(int weight) {
		this.weight = weight;
	}

	/**
	 * @return the eyes
	 */
	public String getEyes() {
		return eyes;
	}

	/**
	 * @param eyes
	 *            the eyes to set
	 */
	public void setEyes(String eyes) {
		this.eyes = eyes;
	}

	/**
	 * @return the hair
	 */
	public String getHair() {
		return hair;
	}

	/**
	 * @param hair
	 *            the hair to set
	 */
	public void setHair(String hair) {
		this.hair = hair;
	}

	public void setPrepareSpellsIsChecked(boolean prepareSpellsIsChecked) {
		this.prepareSpellsIsChecked = prepareSpellsIsChecked;
	}

	public boolean isPrepareSpellsIsChecked() {
		return prepareSpellsIsChecked;
	}
}